﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Google.GData.Calendar;
using Google.GData.Extensions;
using Google.GData.Client;
using System.Windows;

namespace Journal.Helpers
{
    /// <summary>
    /// This class functions as Singleton. Only one instance is created during the run of this application.
    /// It provides basic CRUD operations for google Calendars and Events and can also retrieve
    ///  list of Calendars or events.
    /// </summary>
    public class GoogleServices
    {
        private const string OWN_CALENDARS_FEED_URI = "https://www.google.com/calendar/feeds/default/owncalendars/full";

        private CalendarService calendarService;
        private static GoogleServices instance;

        public enum OrderBy { starttime, endtime };
        public enum SortOrder { ascending, descending };

        private CalendarFeed userCalendars;
        private EventFeed calendarEvents;
        private CalendarQuery calendarQuery;
        private EventQuery eventQuery;

        public CalendarService CalendarService
        {
            get { return calendarService; }
        }

        public static GoogleServices Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new GoogleServices();
                }
                return instance;
            }
        }

        private GoogleServices()
        {
            calendarService = new CalendarService("journal app");
            JournalApp.GetLog(JournalApp.LogType.FileLogger).Debug("GoogleServices initialized");
        }

        public CalendarEntry CreateCalendar(CalendarEntry calendar)
        {
            try
            {
                return calendarService.Insert(new Uri(OWN_CALENDARS_FEED_URI), calendar);
            }
            catch (Exception e)
            {
                Utilities.LogException(e);
                throw;
            }
        }

        public CalendarEntry UpdateCalendar(CalendarEntry calendar)
        {
            try
            {
                return calendar.Update() as CalendarEntry;
            }
            catch (Exception e)
            {
                Utilities.LogException(e);
                throw;
            }
        }

        public void DeleteCalendar (CalendarEntry calendar)
        {
            try
            {
                calendar.Delete();
            }
            catch (Exception e)
            {
                Utilities.LogException(e);
                throw;
            }
        }

        public CalendarFeed RetrieveUserCalendars()
        {
            try
            {
                calendarQuery = new CalendarQuery(OWN_CALENDARS_FEED_URI);
                userCalendars = (CalendarFeed)calendarService.Query(calendarQuery);
                return userCalendars;
            }
            catch (Exception e)
            {
                Utilities.LogException(e);
                throw;
            }
        }

        public EventEntry CreateEvent(Uri postUri, EventEntry thisEvent)
        {
            try
            {
                return calendarService.Insert(postUri, thisEvent);
            }
            catch (Exception e)
            {
                Utilities.LogException(e);
                throw;
            }
        }

        public EventEntry UpdateEvent(EventEntry thisEvent)
        {
            try
            {
                return thisEvent.Update() as EventEntry;
            }
            catch (Exception e)
            {
                Utilities.LogException(e);
                throw;
            }
        }

        public void DeleteEvent(EventEntry thisEvent)
        {
            try
            {
                thisEvent.Delete();
            }
            catch (Exception e)
            {
                Utilities.LogException(e);
                throw;
            }
        }

        public EventFeed RetrieveCalendarEvents(string feedUri)
        {
            try
            {
                eventQuery = new EventQuery(feedUri);
                calendarEvents = (EventFeed)calendarService.Query(eventQuery);
                return calendarEvents;
            }
            catch (Exception e)
            {
                Utilities.LogException(e);
                throw;
            }
        }

        public EventFeed RetrieveCalendarEvents(string feedUri, string orderBy, string sortOrder)
        {
            try
            {
                eventQuery = new EventQuery(feedUri);
                eventQuery.ExtraParameters = "orderby=" + orderBy + "&sortorder=" + sortOrder;
                calendarEvents = (EventFeed)calendarService.Query(eventQuery);
                return calendarEvents;
            }
            catch (Exception e)
            {
                Utilities.LogException(e);
                throw;
            }
        }
    }
}
